package com.util.concurrent.atomic;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.*;

/**
 * @author 宫静雨
 * @version 1.0
 * @since 2023-07-25 14:24:04
 */
@Slf4j
public class AtomicTest {

    @Test
    public void test7() {
        // LongAdder adder = new LongAdder();
        LongAccumulator accumulator = new LongAccumulator(Long::sum, 0);
        for (int i = 1; i <= 10; i++) {
            accumulator.accumulate(i);
        }
        log.info("{}", accumulator);

    }

    @Test
    public void test6() {
        // new AtomicStampedReference<>(new Atomic(), 1);
        // new AtomicMarkableReference<>(new Atomic(), true);

    }

    @Test
    public void test5() {
        Atomic atomic = new Atomic();
        atomic.setF1(11);
        AtomicReference<Atomic> reference = new AtomicReference<>(atomic);
        Atomic a2 = new Atomic();
        a2.setF1(22);
        // reference.set(a2);
        Atomic expect = new Atomic();
        expect.setF1(11);
        reference.compareAndSet(expect, a2);
        log.info("{}", reference);
    }

    @Test
    public void test4() {
        Atomic atomic = new Atomic();
        atomic.setF1(11);
        log.info("{}", atomic);

        AtomicIntegerFieldUpdater<Atomic> f1 = AtomicIntegerFieldUpdater.newUpdater(Atomic.class, "f1");
        f1.set(atomic, 20);
        log.info("{}", atomic);
    }

    @Test
    public void test3() {
        AtomicIntegerArray air = new AtomicIntegerArray(3);
        air.set(0, 1);
        air.set(1, 1);
        air.set(2, 1);
        log.info("{}", air);
    }

    @Test
    public void test2() throws ExecutionException, InterruptedException {
        AtomicInteger ai = new AtomicInteger();
        ExecutorService pool = Executors.newFixedThreadPool(10);

        Future<Integer> future = null;
        for (int i = 0; i < 200000; i++) {
            future = pool.submit(ai::incrementAndGet);
        }
        Integer integer = future.get();
        log.info("{}", integer);
        log.info("{}", ai);
    }

    @Test
    public void test1() {
        AtomicBoolean ab = new AtomicBoolean();
        ab.lazySet(true);
        log.info("{}", ab);
    }

}
